package com.common.rsa;

import com.common.cipher.ICipher;
import com.common.json.JsonUtil;

import javax.crypto.Cipher;
import java.nio.charset.Charset;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @author ZhangHaiWen
 * @title: RSAUtils
 * @projectName JavaSeProject
 * @description: RSA非对称加密工具类
 * @date 2020/12/215:13
 */
public class RSAImple implements ICipher {


    private volatile static RSAImple rsaImple;

    private RSAImple(){

    }

    public static RSAImple getInstance(){
        if(rsaImple == null){
            synchronized (RSAImple.class){
                if(rsaImple == null){
                    rsaImple = new RSAImple();
                }
            }
        }
        return rsaImple;
    }

    /**
     * RSA公钥加密
     *
     * @param content 加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    @Override
    public <T> String encrypt(T content, String publicKey) {
        String outStr = null;
        try {
            // base64编码的公钥
            byte[] decoded = Base64.getDecoder().decode(publicKey.replace("\r\n","").getBytes(Charset.forName("UTF-8")));
            RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            //RSA加密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            byte[] bytes = cipher.doFinal(JsonUtil.toString(content).getBytes(Charset.forName("UTF-8")));
            byte[] decode = Base64.getEncoder().encode(bytes);
            outStr = new String(decode);
        }catch (Exception e){
            e.printStackTrace();
        }
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param str
     *            加密字符串
     * @param privateKey
     *            私钥
     * @return 铭文
     * @throws Exception
     *             解密过程中的异常信息
     */
    @Override
    public String decrypt(String str, String privateKey){
        String outStr = null;
        try {
            //64位解码加密后的字符串
            byte[] inputByte = Base64.getDecoder().decode(str.replace("\r\n","").getBytes(Charset.forName("UTF-8")));
            //base64编码的私钥
            byte[] decoded = Base64.getDecoder().decode(privateKey.getBytes(Charset.forName("UTF-8")));
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            //RSA解密
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            outStr = new String(cipher.doFinal(inputByte));
        }catch (Exception e){
            e.printStackTrace();
        }
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param content
     *            加密字符串
     * @param key
     *            私钥
     * @return 明文
     * @throws Exception
     *             解密过程中的异常信息
     */
    @Override
    public <T> T decrypt(String content, String key, Class<T> tClass) {
        String decrypt = decrypt(content, key);
        return JsonUtil.parse(decrypt, tClass);
    }


//    public static void main(String[] args) {
//        try {
//            //String publicKeyString = encrypt("章海文，hhhh", keyMap.get("publicKeyString"));
//            //System.out.println(String.format("密文:%s",publicKeyString));
//            String privateKeyString = decrypt("S7tRqI5wGdsRrF2JcYy1UkDchHd07W7LY+bDw4D0/yT8x6/UqXQUhbP35Ilrv1cnNtONurQrikC/f6lTDKvhKVedfCNYxPEb9+2sbV8HWa1FiqlICLkOXBdGLk0zdaHfimfK/3LejiJcDMHTXPEn+WuLqdb+Bp/9vZt6sT/OzTc=",
//                   "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKskUjlvSZ00nad/xpttBtXIsU+gN8xIUMMpMtOXzzAx4Orb1mQ9bEMPs4EhDMQzjzf1W4IxCotdGNQNd8uMZxEYoBneJIUQXd6rtNVZ2mIb1n7r1xfnLzp9n9n6r8+4HHbSqY18Q7BBnP4DSZFjfd00oag+oL2ju2mLHMs5VYf9AgMBAAECgYEAmkxp8ax7c0fv6AdUuebnZbHG4yJxjDWa0wn+8DSLsUkXHshLmB6k0CWE0qRIjVBrDKmi8lNizVmHPBBUdGlGtfK1hJOEnAEJmliJ21NGHpVltCibKivhvnQucMVUobC63xlOH3qvGZMp11ccfFdH2aG/hw+xVSGOsXqnCLncpgUCQQDWEay2ykhc0Uh+04i2LfVWBB927jVn88LiAjSwHqXgSRh5RqFxkFM7O3hT6lYpydbKLfVH1G37wFmmNW41/jCzAkEAzKoY8ODDDEhLa4zYPl8ISfpHKrQ24N87xmr/cwBcARhz16eSq31HSp8wryA0AQThXGM9iWuHyiyfWoBLKchcjwJAairT5MgIAXiOItBYkjnS3jknPb3AYPDlK1/6r4pTrBu0dplQAlmY3dyNvdiPqSQAUb9fUaOKdHweOi9vnHmXvwJAKGT+LTS/aoIuWJjg6VaKZUd/ml8dYb7Npnjh2Ene3tx7qLnLSguc8Y5/5mC9wuG6tShlMeVGVNH/1bXyn9mK4wJBAJAMQfwBAWUu+4Lh/FEiEfgMTsr8YR5+4jdvbPEcWmE6iAdk+Ul5OLiTCAYi1kgFV33kqv5Wry2ZmKSCh8MzCLU=");
//            System.out.println(String.format("解密结果密文:%s",privateKeyString));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

}
